home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / xmbase-grok-1.2 / parser.y < prev    next >
Text File  |  1995-06-25  |  11KB  |  312 lines

  1. %{
  2. #include "config.h"
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <time.h>
  7. #include <math.h>
  8. #include <Xm/Xm.h>
  9. #include "grok.h"
  10. #include "form.h"
  11. #include "proto.h"
  12.  
  13. extern char    yyret[32768];
  14. extern CARD    *yycard;    /* current card to evaluate for */
  15. extern Display    *display;    /* current X screen */
  16. extern Widget    toplevel;    /* for error popups */
  17. extern char    *prev_form;    /* previous form loaded, curr is in <card> */
  18. extern char    *switch_name;    /* if switch statement was found, name to */
  19. extern char    *switch_expr;    /* .. switch to and search expression */
  20.  
  21. static struct var {
  22.     char    *string;
  23.     double    value;
  24.     BOOL    numeric;
  25. } var[26];    /*<<<*/
  26.  
  27. static int    f_len    (char  *s)  { return(s ? strlen(s) : 0); }
  28. static void    f_free    (char  *s)  { if (s) free((void *)s); }
  29. static char    *f_str    (double d)  { char buf[100]; sprintf(buf,"%.12lg",d);
  30.                     return(mystrdup(buf)); }
  31. static int    f_cmp    (char  *s,
  32.              char  *t)  { return(strcmp(s?s:"", t?t:"")); }
  33.  
  34. static char    *getsvar    (int    v)  { char buf[100], *r = var[v].string;
  35.                     if (var[v].numeric) { sprintf(r = buf,
  36.                             "%g", var[v].value); }
  37.                     return(mystrdup(r)); }
  38. static double   getnvar    (int    v)  { return(var[v].numeric ? var[v].value :
  39.                     var[v].string?atof(var[v].string):0);}
  40. static char    *setsvar    (int    v,
  41.              char  *s)  { f_free(var[v].string);
  42.                     var[v].numeric = FALSE;
  43.                     return(mystrdup(var[v].string = s)); }
  44. static double   setnvar    (int    v,
  45.              double d)  { (void)setsvar(v, 0);
  46.                     var[v].numeric = TRUE;
  47.                     return(var[v].value = d); }
  48.  
  49. void init_variables(void) { int i; for (i=0; i < 26; i++) setsvar(i, 0); }
  50. %}
  51.  
  52. %union { int ival; double dval; char *sval; struct arg *aval; }
  53. %type    <dval>    number
  54. %type    <sval>    string
  55. %type    <aval>    args
  56. %token    <dval>    NUMBER
  57. %token    <sval>    STRING SYMBOL
  58. %token    <ival>    FIELD VAR
  59. %token        EQ NEQ LE GE SHR SHL AND OR IN
  60. %token        PLA MIA MUA MOA DVA ANA ORA INC DEC APP
  61. %token        AVG DEV AMIN AMAX SUM
  62. %token        QAVG QDEV QMIN QMAX QSUM
  63. %token        SAVG SDEV SMIN SMAX SSUM
  64. %token        ABS INT BOUND LEN CHOP SUBSTR SQRT EXP LOG LN POW RANDOM
  65. %token        SIN COS TAN ASIN ACOS ATAN ATAN2
  66. %token        DATE TIME DURATION
  67. %token        YEAR MONTH DAY HOUR MINUTE SECOND LEAP JULIAN
  68. %token        SECTION_ DBASE_ FORM_ PREVFORM SWITCH THIS LAST
  69. %token        HOST USER UID GID SYSTEM ACCESS BEEP ERROR PRINTF
  70.  
  71. %left ',' ';'
  72. %right '?' ':'
  73. %right PLA MIA MUA MOA DVA ANA ORA APP '='
  74. %left OR
  75. %left AND
  76. %left '|'
  77. %left '^'
  78. %left '&'
  79. %left IN
  80. %left EQ NEQ
  81. %left '<' '>' LE GE
  82. %left SHL SHR
  83. %left '-' '+'
  84. %left '*' '/' '%'
  85. %nonassoc '!' '~' UMINUS
  86. %left '.'
  87.  
  88. %start stmt
  89.  
  90. %%
  91. stmt    : string            { char *s = $1; if (s)
  92.                       strncpy(yyret, s, sizeof(yyret));
  93.                       f_free(s); }
  94.     ;
  95.  
  96. string    : STRING            { $$ = $1; }
  97.     | '{' string '}'        { $$ = $2; }
  98.     | string ';' string        { $$ = $3; f_free($1); }
  99.     | string '.' string        { char *s=$1, *t=$3, *r=
  100.                          malloc(f_len(s)+f_len(t)+1); *r=0;
  101.                       if (s) strcpy(r, s); f_free(s);
  102.                       if (t) strcat(r, t); f_free(t);
  103.                       $$ = r; }
  104.     | VAR                { $$ = getsvar($1); }
  105.     | VAR APP string        { int v=$1;
  106.                       char *s=getsvar(v), *t=$3, *r=
  107.                          malloc(f_len(s)+f_len(t)+1); *r=0;
  108.                       if (s) strcpy(r, s); f_free(s);
  109.                       if (t) strcat(r, t); f_free(t);
  110.                       $$ = setsvar(v, r); }
  111.     | VAR '=' string        { $$ = setsvar($1, $3);}
  112.     | '(' number ')'        { $$ = f_str($2); }
  113.     | string '?' string ':' string    { $$ = f_num($1) ? $3 : $5; }
  114.     | string '<' string        { $$ = f_str((double)
  115.                             (f_cmp($1, $3) <  0));}
  116.     | string '>' string        { $$ = f_str((double)
  117.                             (f_cmp($1, $3) >  0));}
  118.     | string EQ  string        { $$ = f_str((double)
  119.                             (f_cmp($1, $3) == 0));}
  120.     | string NEQ string        { $$ = f_str((double)
  121.                             (f_cmp($1, $3) != 0));}
  122.     | string LE  string        { $$ = f_str((double)
  123.                             (f_cmp($1, $3) <= 0));}
  124.     | string GE  string        { $$ = f_str((double)
  125.                             (f_cmp($1, $3) >= 0));}
  126.     | string IN  string        { $$ = f_str((double)f_instr($1, $3));}
  127.     | FIELD                { $$ = f_field($1, yycard->row); }
  128.     | FIELD '[' number ']'        { $$ = f_field($1, $3); }
  129.     | SYSTEM '(' string ')'        { $$ = f_system($3); }
  130.     | '$' SYMBOL            { $$ = mystrdup(getenv($2)); }
  131.     | CHOP '(' string ')'        { char *s=$3; if (s) { int n=strlen(s);
  132.                       if (n && s[n-1]=='\n') s[n-1] = 0; }
  133.                       $$ = s; }
  134.     | SUBSTR '(' string ',' number ',' number ')'
  135.                     { $$ = f_substr($3, (int)$5, (int)$7);}
  136.     | HOST                { char s[80]; if (gethostname(s, 80))
  137.                       *s=0; s[80-1]=0; $$ = mystrdup(s); }
  138.     | USER                { $$ = mystrdup(getenv("USER")); }
  139.     | PREVFORM            { $$ = mystrdup(prev_form); }
  140.     | SECTION_            { $$ = !yycard || !yycard->dbase ? 0 :
  141.                         mystrdup(section_name(
  142.                             yycard->dbase,
  143.                             yycard->dbase->currsect));}
  144.     | SECTION_ '[' number ']'    { $$ = mystrdup(section_name(
  145.                             yycard->dbase,
  146.                             f_section($3))); }
  147.     | FORM_                { $$ = yycard && yycard->form
  148.                               && yycard->form->name ?
  149.                         mystrdup(resolve_tilde
  150.                         (yycard->form->name, "gf")):0;}
  151.     | DBASE_            { $$ = yycard && yycard->form
  152.                               && yycard->form->dbase ?
  153.                         mystrdup(resolve_tilde
  154.                             (yycard->form->dbase,
  155.                              yycard->form->proc ?
  156.                                 0 : "db")) :0;}
  157.     | SWITCH '(' string ',' string ')'
  158.                     { char *name = $3, *expr = $5;
  159.                       f_free(switch_name);
  160.                       f_free(switch_expr);
  161.                       switch_name = mystrdup(name);
  162.                       switch_expr = mystrdup(expr);
  163.                       f_free(name); f_free(expr); $$ = 0; }
  164.     | TIME                { $$ = mystrdup(mktimestring
  165.                         (time(0), FALSE)); }
  166.     | DATE                { $$ = mystrdup(mkdatestring
  167.                         (time(0))); }
  168.     | TIME '(' number ')'        { $$ = mystrdup(mktimestring
  169.                         ((time_t)$3, FALSE)); }
  170.     | DATE '(' number ')'        { $$ = mystrdup(mkdatestring
  171.                         ((time_t)$3)); }
  172.     | DURATION '(' number ')'    { $$ = mystrdup(mktimestring
  173.                         ((time_t)$3, TRUE)); }
  174.     | PRINTF '(' args ')'        { $$ = f_printf($3); }
  175.     | BEEP                { XBell(display, 0); $$ = 0; }
  176.     | ERROR '(' args ')'        { char *s = f_printf($3);
  177.                       create_error_popup(toplevel, 0, s);
  178.                       f_free(s); $$ = 0; }
  179.     ;
  180.  
  181. args    : string            { $$ = f_addarg(0, $1); }
  182.     | args ',' string        { $$ = f_addarg($1, $3); }
  183.     ;
  184.  
  185. number    : NUMBER            { $$ = $1; }
  186.     | '{' string '}'        { $$ = f_num($2); }
  187.     | '(' number ')'        { $$ = $2; }
  188.     | FIELD                { $$ = f_num(f_field($1,yycard->row));}
  189.     | FIELD '[' number ']'        { $$ = f_num(f_field($1, $3)); }
  190.     | VAR                { $$ = getnvar($1); }
  191.     | VAR '=' number        { $$ = setnvar($1, $3); }
  192.     | VAR PLA number        { int v = $1;
  193.                       $$ = setnvar(v, getnvar(v) + $3); }
  194.     | VAR MIA number        { int v = $1;
  195.                       $$ = setnvar(v, getnvar(v) - $3); }
  196.     | VAR MUA number        { int v = $1;
  197.                       $$ = setnvar(v, getnvar(v) * $3); }
  198.     | VAR DVA number        { int v = $1; double d=$3; if(d==0)d=1;
  199.                       $$ = setnvar(v, getnvar(v) / d); }
  200.     | VAR MOA number        { int v = $1; double d=$3; if(d==0)d=1;
  201.                       $$ = setnvar(v, (double)((int)
  202.                               getnvar(v)%(int)d));}
  203.     | VAR ANA number        { int v = $1;
  204.                       $$ = setnvar(v, (double)((int)$3 &
  205.                               (int)getnvar(v))); }
  206.     | VAR ORA number        { int v = $1;
  207.                       $$ = setnvar(v, (double)((int)$3 |
  208.                               (int)getnvar(v))); }
  209.     | VAR INC            { int v = $1;
  210.                       $$ = setnvar(v, getnvar(v) + 1) - 1;}
  211.     | VAR DEC            { int v = $1;
  212.                       $$ = setnvar(v, getnvar(v) - 1) + 1;}
  213.     | INC VAR            { int v = $2;
  214.                       $$ = setnvar(v, getnvar(v) + 1); }
  215.     | DEC VAR            { int v = $2;
  216.                       $$ = setnvar(v, getnvar(v) - 1); }
  217.     | '-' number %prec UMINUS    { $$ = - $2; }
  218.     | '!' number            { $$ = ! $2; }
  219.     | '~' number            { $$ = ~ (int)$2; }
  220.     | number '&' number        { $$ = (int)$1 &  (int)$3; }
  221.     | number '^' number        { $$ = (int)$1 ^  (int)$3; }
  222.     | number '|' number        { $$ = (int)$1 |  (int)$3; }
  223.     | number SHL number        { $$ = (int)$1 << (int)$3; }
  224.     | number SHR number        { $$ = (int)$1 >> (int)$3; }
  225.     | number '%' number        { int i=$3; if (i==0) i=1;
  226.                       $$ = (int)$1 % i; }
  227.     | number '+' number        { $$ = $1 +  $3; }
  228.     | number '-' number        { $$ = $1 -  $3; }
  229.     | number '*' number        { $$ = $1 *  $3; }
  230.     | number '/' number        { double d=$3; if (d==0) d=1;
  231.                       $$ = $1 /  d; }
  232.     | number '<' number        { $$ = $1 <  $3; }
  233.     | number '>' number        { $$ = $1 >  $3; }
  234.     | number EQ  number        { $$ = $1 == $3; }
  235.     | number NEQ number        { $$ = $1 != $3; }
  236.     | number LE  number        { $$ = $1 <= $3; }
  237.     | number GE  number        { $$ = $1 >= $3; }
  238.     | number AND number        { $$ = $1 && $3; }
  239.     | number OR  number        { $$ = $1 || $3; }
  240.     | number '?' number ':' number    { $$ = $1 ?  $3 : $5; }
  241.     | number ',' number        { $$ = $3; }
  242.     | THIS                { $$ = yycard && yycard->row > 0 ?
  243.                            yycard->row : 0; }
  244.     | LAST                { $$ = yycard && yycard->dbase ?
  245.                            yycard->dbase->nrows - 1 : -1; }
  246.     | AVG   '(' FIELD ')'        { $$ = f_avg($3); }
  247.     | DEV   '(' FIELD ')'        { $$ = f_dev($3); }
  248.     | AMIN  '(' FIELD ')'        { $$ = f_min($3); }
  249.     | AMAX  '(' FIELD ')'        { $$ = f_max($3); }
  250.     | SUM   '(' FIELD ')'        { $$ = f_sum($3); }
  251.     | QAVG  '(' FIELD ')'        { $$ = f_qavg($3); }
  252.     | QDEV  '(' FIELD ')'        { $$ = f_qdev($3); }
  253.     | QMIN  '(' FIELD ')'        { $$ = f_qmin($3); }
  254.     | QMAX  '(' FIELD ')'        { $$ = f_qmax($3); }
  255.     | QSUM  '(' FIELD ')'        { $$ = f_qsum($3); }
  256.     | SAVG  '(' FIELD ')'        { $$ = f_savg($3); }
  257.     | SDEV  '(' FIELD ')'        { $$ = f_sdev($3); }
  258.     | SMIN  '(' FIELD ')'        { $$ = f_smin($3); }
  259.     | SMAX  '(' FIELD ')'        { $$ = f_smax($3); }
  260.     | SSUM  '(' FIELD ')'        { $$ = f_ssum($3); }
  261.     | ABS   '(' number ')'        { $$ = abs($3); }
  262.     | INT   '(' number ')'        { $$ = (int)($3); }
  263.     | BOUND '(' number ',' number ',' number ')'
  264.                     { register double a=$3, b=$5, c=$7;
  265.                       $$ = a < b ? b : a > c ? c : a; }
  266.     | LEN   '(' string ')'        { char *a=$3; $$ = a ? f_len(a) : 0;
  267.                                 f_free(a); }
  268.     | SQRT  '(' number ')'        { $$ = sqrt(abs($3));  }
  269.     | EXP   '(' number ')'        { $$ = exp($3); }
  270.     | LOG   '(' number ')'        { double a=$3; $$ = a<=0 ? 0:log10(a);}
  271.     | LN    '(' number ')'        { double a=$3; $$ = a<=0 ? 0:log(a); }
  272.     | POW   '(' number ',' number ')'
  273.                     { $$ = pow($3, $5); }
  274.     | RANDOM            { $$ = drand48(); }
  275.     | SIN   '(' number ')'        { $$ = sin($3); }
  276.     | COS   '(' number ')'        { $$ = cos($3); }
  277.     | TAN   '(' number ')'        { $$ = tan($3); }
  278.     | ASIN  '(' number ')'        { $$ = asin($3); }
  279.     | ACOS  '(' number ')'        { $$ = acos($3); }
  280.     | ATAN  '(' number ')'        { $$ = atan($3); }
  281.     | ATAN2 '(' number ',' number ')'
  282.                     { $$ = atan2($3, $5); }
  283.     | SECTION_            { $$ = yycard && yycard->dbase ?
  284.                         yycard->dbase->currsect : 0; }
  285.     | SECTION_ '[' number ']'    { $$ = f_section($3); }
  286.     | DATE                { $$ = time(0); }
  287.     | YEAR  '(' number ')'        { const long t = $3;
  288.                       $$ = localtime(&t)->tm_year; }
  289.     | MONTH '(' number ')'        { const long t = $3;
  290.                       $$ = localtime(&t)->tm_mon+1; }
  291.     | DAY   '(' number ')'        { const long t = $3;
  292.                       $$ = localtime(&t)->tm_mday; }
  293.     | HOUR  '(' number ')'        { const long t = $3;
  294.                       $$ = localtime(&t)->tm_hour; }
  295.     | MINUTE '(' number ')'        { const long t = $3;
  296.                       $$ = localtime(&t)->tm_min; }
  297.     | SECOND '(' number ')'        { const long t = $3;
  298.                       $$ = localtime(&t)->tm_sec; }
  299.     | JULIAN '(' number ')'        { const long t = $3;
  300.                       $$ = localtime(&t)->tm_yday; }
  301.     | LEAP   '(' number ')'        { const long t = $3;
  302.                       int y=localtime(&t)->tm_year;
  303.                       $$ = !(y%4) ^ !(y%100) ^ !(y%400); }
  304.     | UID                { $$ = getuid(); }
  305.     | GID                { $$ = getgid(); }
  306.     | ACCESS '(' string ',' number ')'
  307.                     { char *a = $3;
  308.                       $$ = a ? access(a, (int)$5) : 0;
  309.                       f_free(a); }
  310.     ;
  311. %%
  312.